package com.zg.service;


import com.zg.handler.ChildChannelHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.stereotype.Component;


import java.net.InetSocketAddress;

@Component
public class MqttBrokerService {
    NioEventLoopGroup boss =null;//默认线程数为cpu的2倍
    NioEventLoopGroup work = null;

    public void start(InetSocketAddress inetSocketAddress){
        init(inetSocketAddress);
    }

    public void init(InetSocketAddress inetSocketAddress){
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        try {
            boss = new NioEventLoopGroup();//默认线程数为cpu的2倍
            work = new NioEventLoopGroup();

            //配置相关信息


            serverBootstrap.group(boss,work)
                    .channel(NioServerSocketChannel.class)//设置为nio管道通信，Oio是阻塞的
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChildChannelHandler())
                    .option(ChannelOption.SO_BACKLOG, 1024)//工作还没完成时的等待队列
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.TCP_NODELAY, true)
                    .childOption(ChannelOption.SO_REUSEADDR,true)//快速复用
            ;

            ChannelFuture channelFuture = serverBootstrap.bind(inetSocketAddress).addListener(future -> {
                if (future.isSuccess()) {
                    System.out.println("线程："+Thread.currentThread().getName()+" netty 绑定ip："+inetSocketAddress.getHostName()+" 端口["+inetSocketAddress.getPort()+"]绑定成功!");
                } else {
                    System.err.println("netty 端口["+inetSocketAddress.getPort()+"]绑定失败!");
                }
            }).sync();

            channelFuture.channel().closeFuture().sync();//关闭，应为是基于异步响应式编程，所以需要等待同步关闭

        }catch (InterruptedException e){
            System.out.println(e.getMessage());
        }finally {
            work.shutdownGracefully();
            boss.shutdownGracefully();
        }

    }

    public void shutdown(){
        if (boss!=null&&work!=null){
            boss.shutdownGracefully();
            work.shutdownGracefully();
            System.out.println("shutdown success");
        }
    }

}
